home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 11 / Info-Mac_XI_Disc_1.cdr_ / Info-Mac XI Disc 1.cdr / Programs / Science & Math / MacEspresso 1.0 / espresso / sharp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-26  |  4.8 KB  |  239 lines  |  [TEXT/R*ch]

  1. /*
  2.     sharp.c -- perform sharp, disjoint sharp, and intersection
  3. */
  4.  
  5. #include "espresso.h"
  6.  
  7. long start_time;
  8.  
  9.  
  10. /* cv_sharp -- form the sharp product between two covers */
  11. pcover cv_sharp(A, B)
  12. pcover A, B;
  13. {
  14.     pcube last, p;
  15.     pcover T;
  16.  
  17.     T = new_cover(0);
  18.     foreach_set(A, last, p)
  19.     T = sf_union(T, cb_sharp(p, B));
  20.     return T;
  21. }
  22.  
  23.  
  24. /* cb_sharp -- form the sharp product between a cube and a cover */
  25. pcover cb_sharp(c, T)
  26. pcube c;
  27. pcover T;
  28. {
  29.     if (T->count == 0) {
  30.     T = sf_addset(new_cover(1), c);
  31.     } else {
  32.     start_time = ptime();
  33.     T = cb_recur_sharp(c, T, 0, T->count-1, 0);
  34.     }
  35.     return T;
  36. }
  37.  
  38.  
  39. /* recursive formulation to provide balanced merging */
  40. pcover cb_recur_sharp(c, T, first, last, level)
  41. pcube c;
  42. pcover T;
  43. int first, last, level;
  44. {
  45.     pcover temp, left, right;
  46.     int middle;
  47.  
  48.     if (first == last) {
  49.     temp = sharp(c, GETSET(T, first));
  50.     } else {
  51.     middle = (first + last) / 2;
  52.     left = cb_recur_sharp(c, T, first, middle, level+1);
  53.     right = cb_recur_sharp(c, T, middle+1, last, level+1);
  54.     temp = cv_intersect(left, right);
  55.     if ((debug & SHARP) && level < 4) {
  56.         printf("# SHARP[%d]: %4d = %4d x %4d, time = %s\n",
  57.         level, temp->count, left->count, right->count,
  58.         print_time(ptime() - start_time));
  59.         (void) fflush(stdout);
  60.     }
  61.     free_cover(left);
  62.     free_cover(right);
  63.     }
  64.     return temp;
  65. }
  66.  
  67.  
  68. /* sharp -- form the sharp product between two cubes */
  69. pcover sharp(a, b)
  70. pcube a, b;
  71. {
  72.     register int var;
  73.     register pcube d=cube.temp[0], temp=cube.temp[1], temp1=cube.temp[2];
  74.     pcover r = new_cover(cube.num_vars);
  75.  
  76.     if (cdist0(a, b)) {
  77.     set_diff(d, a, b);
  78.     for(var = 0; var < cube.num_vars; var++) {
  79.         if (! setp_empty(set_and(temp, d, cube.var_mask[var]))) {
  80.         set_diff(temp1, a, cube.var_mask[var]);
  81.         set_or(GETSET(r, r->count++), temp, temp1);
  82.         }
  83.     }
  84.     } else {
  85.     r = sf_addset(r, a);
  86.     }
  87.     return r;
  88. }
  89.  
  90. pcover make_disjoint(A)
  91. pcover A;
  92. {
  93.     pcover R, new;
  94.     register pset last, p;
  95.  
  96.     R = new_cover(0);
  97.     foreach_set(A, last, p) {
  98.     new = cb_dsharp(p, R);
  99.     R = sf_append(R, new);
  100.     }
  101.     return R;
  102. }
  103.  
  104.  
  105. /* cv_dsharp -- disjoint-sharp product between two covers */
  106. pcover cv_dsharp(A, B)
  107. pcover A, B;
  108. {
  109.     register pcube last, p;
  110.     pcover T;
  111.  
  112.     T = new_cover(0);
  113.     foreach_set(A, last, p) {
  114.     T = sf_union(T, cb_dsharp(p, B));
  115.     }
  116.     return T;
  117. }
  118.  
  119.  
  120. /* cb1_dsharp -- disjoint-sharp product between a cover and a cube */
  121. pcover cb1_dsharp(T, c)
  122. pcover T;
  123. pcube c;
  124. {
  125.     pcube last, p;
  126.     pcover R;
  127.  
  128.     R = new_cover(T->count);
  129.     foreach_set(T, last, p) {
  130.     R = sf_union(R, dsharp(p, c));
  131.     }
  132.     return R;
  133. }
  134.  
  135.  
  136. /* cb_dsharp -- disjoint-sharp product between a cube and a cover */
  137. pcover cb_dsharp(c, T)
  138. pcube c;
  139. pcover T;
  140. {
  141.     pcube last, p;
  142.     pcover Y, Y1;
  143.  
  144.     if (T->count == 0) {
  145.     Y = sf_addset(new_cover(1), c);
  146.     } else {
  147.     Y = new_cover(T->count);
  148.     set_copy(GETSET(Y,Y->count++), c);
  149.     foreach_set(T, last, p) {
  150.         Y1 = cb1_dsharp(Y, p);
  151.         free_cover(Y);
  152.         Y = Y1;
  153.     }
  154.     }
  155.     return Y;
  156. }
  157.  
  158.  
  159. /* dsharp -- form the disjoint-sharp product between two cubes */
  160. pcover dsharp(a, b)
  161. pcube a, b;
  162. {
  163.     register pcube mask, diff, and, temp, temp1 = cube.temp[0];
  164.     int var;
  165.     pcover r;
  166.  
  167.     r = new_cover(cube.num_vars);
  168.  
  169.     if (cdist0(a, b)) {
  170.     diff = set_diff(new_cube(), a, b);
  171.     and = set_and(new_cube(), a, b);
  172.     mask = new_cube();
  173.     for(var = 0; var < cube.num_vars; var++) {
  174.         /* check if position var of "a and not b" is not empty */
  175.         if (! setp_disjoint(diff, cube.var_mask[var])) {
  176.  
  177.         /* coordinate var equals the difference between a and b */
  178.         temp = GETSET(r, r->count++);
  179.         (void) set_and(temp, diff, cube.var_mask[var]);
  180.  
  181.         /* coordinates 0 ... var-1 equal the intersection */
  182.         INLINEset_and(temp1, and, mask);
  183.         INLINEset_or(temp, temp, temp1);
  184.  
  185.         /* coordinates var+1 .. cube.num_vars equal a */
  186.         set_or(mask, mask, cube.var_mask[var]);
  187.         INLINEset_diff(temp1, a, mask);
  188.         INLINEset_or(temp, temp, temp1);
  189.         }
  190.     }
  191.     free_cube(diff);
  192.     free_cube(and);
  193.     free_cube(mask);
  194.     } else {
  195.     r = sf_addset(r, a);
  196.     }
  197.     return r;
  198. }
  199.  
  200. /* cv_intersect -- form the intersection of two covers */
  201.  
  202. #define MAGIC 500               /* save 500 cubes before containment */
  203.  
  204. pcover cv_intersect(A, B)
  205. pcover A, B;
  206. {
  207.     register pcube pi, pj, lasti, lastj, pt;
  208.     pcover T, Tsave = NULL;
  209.  
  210.     /* How large should each temporary result cover be ? */
  211.     T = new_cover(MAGIC);
  212.     pt = T->data;
  213.  
  214.     /* Form pairwise intersection of each cube of A with each cube of B */
  215.     foreach_set(A, lasti, pi) {
  216.     foreach_set(B, lastj, pj) {
  217.         if (cdist0(pi, pj)) {
  218.         (void) set_and(pt, pi, pj);
  219.         if (++T->count >= T->capacity) {
  220.             if (Tsave == NULL)
  221.             Tsave = sf_contain(T);
  222.             else
  223.             Tsave = sf_union(Tsave, sf_contain(T));
  224.             T = new_cover(MAGIC);
  225.             pt = T->data;
  226.         } else
  227.             pt += T->wsize;
  228.         }
  229.     }
  230.     }
  231.  
  232.  
  233.     if (Tsave == NULL)
  234.     Tsave = sf_contain(T);
  235.     else
  236.     Tsave = sf_union(Tsave, sf_contain(T));
  237.     return Tsave;
  238. }
  239.